package cc.magicjson.spring.exploration.analyze;

import cc.magicjson.spring.exploration.service.DemoService;
import lombok.RequiredArgsConstructor;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.stream.IntStream;

@Component
// @Component 注解标记这个类为 Spring 管理的组件，使其能被自动扫描和注册
@RequiredArgsConstructor
// @RequiredArgsConstructor 是 Lombok 注解，自动为所有 final 字段生成构造函数
public class DemoAnalyzer implements CommandLineRunner {
    // CommandLineRunner 接口允许在 SpringApplication 运行完成后执行额外的代码

    private final DemoService demoService;
    // 注入 DemoService，用于演示和分析

    private final Advisor infrastructureAdvisor;
    // 注入被 @Role(ROLE_INFRASTRUCTURE) 标记的 Advisor

    private final Advisor regularAdvisor;
    // 注入普通的 Advisor，用于对比

    private Object getCachedAdvisor(Advisor advisor) {
        // 模拟缓存查找操作
        // 在实际应用中，这里可能会涉及复杂的缓存逻辑
        return advisor;
    }

    @Override
    public void run(String... args) {
        // CommandLineRunner 接口的 run 方法实现
        // 在应用启动后自动执行
        analyze();
    }

    public void analyze() {
        // 分析方法，执行一系列检查和演示

        // 检查 DemoService 是否被代理
        System.out.println("Is DemoService proxied? " + AopUtils.isAopProxy(demoService));
        
        if (AopUtils.isAopProxy(demoService)) {
            // 如果 DemoService 被代理，获取并打印应用到它的所有 Advisors
            Advised advised = (Advised) demoService;
            Advisor[] advisors = advised.getAdvisors();
            System.out.println("Advisors applied to DemoService:");
            for (Advisor advisor : advisors) {
                System.out.println(" - " + advisor.getClass().getSimpleName());
            }
        }

        // 检查 infrastructureAdvisor 是否被代理
        System.out.println("Is infrastructureAdvisor proxied? " + AopUtils.isAopProxy(infrastructureAdvisor));
        
        // 检查 regularAdvisor 是否被代理
        System.out.println("Is regularAdvisor proxied? " + AopUtils.isAopProxy(regularAdvisor));

        // 模拟对 infrastructureAdvisor 的缓存检查
        System.out.println("Simulating cache check for infrastructureAdvisor");
        IntStream.range(0, 5)
            .mapToObj(i -> measureCacheLookupTime(infrastructureAdvisor))
            .forEach(time -> System.out.println("Infrastructure Advisor cache lookup time: " + time + " ns"));

        // 添加对 regularAdvisor 的缓存检查
        System.out.println("\nSimulating cache check for regularAdvisor");
        IntStream.range(0, 5)
            .mapToObj(i -> measureCacheLookupTime(regularAdvisor))
            .forEach(time -> System.out.println("Regular Advisor cache lookup time: " + time + " ns"));
    }

    private long measureCacheLookupTime(Advisor advisor) {
        long start = System.nanoTime();
        getCachedAdvisor(advisor);
        long end = System.nanoTime();
        return end - start;
    }
}
